using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing.Drawing2D;
using System.Drawing;
using Mpi.Common;

namespace Xeml.Visualization
{
    public abstract class VisualTimeElement
    {
        #region Fields
        protected GraphicsPath shape;
        protected float x;
        protected float y;
        protected bool isHighLighted;
        protected bool selected;
        protected SizeF size;

        #endregion

        #region Properties

        public abstract TimeSpan Time
        {
            get;
            set;
        }

        public float X
        {
            get
            {
                return this.x;
            }
            set
            {
                if (this.x != value)
                {
                    this.x = value;
                    SetShape();
                }
            }
        }

        public float Y
        {
            get
            {
                return this.y;
            }
            set
            {
                if (this.y != value)
                {
                    this.y = value;
                    SetShape();
                }
            }
        }

        public SizeF Size
        {
            get
            {
                return this.size;
            }
            set
            {
                if (this.size != value)
                {
                    this.size = value;
                    SetShape();
                }
            }
        }

        public GraphicsPath Shape
        {
            get { return shape; }
        }


        public RectangleF BoundsF
        {
            get
            {
                return this.shape.GetBounds();
            }
        }

        public Rectangle Bounds
        {
            get
            {
                return Rectangle.Round(BoundsF);
            }
        }

        public bool IsHighLighted
        {
            get { return isHighLighted; }
            set 
            {
                if (isHighLighted != value)
                {
                    isHighLighted = value;
                    OnHighLightChanged();
                }
            }
        }

        public virtual bool Selected
        {
            get { return selected; }
            set 
            {
                if (selected != value)
                {
                    selected = value;
                    if (selected)
                        OnSelection();
                    else
                        OnDeSelection();
                }
            }
        } 
        #endregion

        #region Methods
        protected abstract void SetShape();

        public virtual void TrySelect(int x, int y, bool multiSelect)
        {
            if (multiSelect)
            {
                if (this.shape.IsVisible(x, y))
                {
                    this.Selected = !this.Selected;
                    OnTouched();
                }
            }
            else
            {
                if (this.shape.IsVisible(x, y))
                {
                    this.Selected = true;
                    OnTouched();
                }
                else
                    this.Selected = false;
            }
        }

        public void TryHighLight(int x, int y)
        {
            if (this.shape.IsVisible(x, y))
                this.IsHighLighted = true;
            else
                this.IsHighLighted = false;
        }

        



        #endregion

        #region Event- / handling

        public event EventHandler<PropertyHasChangedEventArgs<TimeSpan>> XLocationUpdateNeeded;
        public event EventHandler Selection;
        public event EventHandler DeSelection;
        public event EventHandler HighLightChanged;
        public event EventHandler Touched;

        protected virtual void OnXLocationUpdateNeeded(PropertyHasChangedEventArgs<TimeSpan> timeEventArgs)
        {
            if (XLocationUpdateNeeded != null)
                XLocationUpdateNeeded(this, timeEventArgs );
        }

        protected virtual void OnHighLightChanged()
        {
            if (HighLightChanged != null)
                HighLightChanged(this, new EventArgs());
        }

        protected virtual void OnSelection()
        {
            if (Selection != null)
                Selection(this, new EventArgs());
        }

        protected virtual void OnDeSelection()
        {
            if (DeSelection != null)
                DeSelection(this, new EventArgs());
        }

        protected virtual void OnTouched()
        {
            if (Touched != null)
                Touched(this, new EventArgs());
        }
        
        #endregion

    }
}
